package com.ktwlrj.securitycenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktwlrj.core.base.DetailEntity;
import com.ktwlrj.core.constant.ResultCode;
import com.ktwlrj.core.exception.ActionException;
import com.ktwlrj.core.util.ContextHolderUtils;
import com.ktwlrj.core.util.convert.ConvertUtil;
import com.ktwlrj.securitycenter.controller.args.*;
import com.ktwlrj.securitycenter.dto.SafeApproveDto;
import com.ktwlrj.securitycenter.dto.SafeCredentialDto;
import com.ktwlrj.securitycenter.dto.SafeInterceptDto;
import com.ktwlrj.securitycenter.dto.SafeInterceptPageDto;
import com.ktwlrj.securitycenter.em.LockStatusEnum;
import com.ktwlrj.securitycenter.entity.SafeInterceptEntity;
import com.ktwlrj.securitycenter.mapper.SafeInterceptMapper;
import com.ktwlrj.securitycenter.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * (SafeIntercept)业务层实现
 *
 * @author code generation
 * @date 2020-02-24 18:08:13
 * @since JDK1.8
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SafeInterceptServiceImpl extends ServiceImpl<SafeInterceptMapper, SafeInterceptEntity>
        implements SafeInterceptService {
    private final SafeInterceptMapper mapper;
    private final SafeCredentialService credentialService;
    private final SafeInterceptRuleService interceptRuleService;
    private final SafeInterceptTargetService interceptTargetService;
    private final StringEncryptor encryptor;
    private final SafeApproveService safeApproveService;
    private final ContextHolderUtils contextHolderUtils;

    @Override
    public void save(SafeInterceptArgs args) throws RuntimeException {
        DetailEntity detailEntity = contextHolderUtils.getDetailEntity();
        SafeInterceptEntity entity = ConvertUtil.map(args, SafeInterceptEntity.class);
        entity.setInterceptId(null);
        entity.setVersion(null);
        entity.setApproveStatus(0);
        entity.setOrgId(detailEntity.getCurrentOrgId());
        entity.setOrgName(detailEntity.getCurrentOrgName());
        boolean result = super.save(entity);
        if (!result) {
            throw new ActionException(ResultCode.DATABASE_INSER_ERROR);
        }
        // 保存明细
        saveDetails(entity.getInterceptId(), args);
    }

    @Override
    public void updateById(SafeInterceptArgs args) throws RuntimeException {
        // 查询数据是否存在
        SafeInterceptEntity orgEntity = this.getEntityById(args.getInterceptId());
        if (orgEntity.getApproveStatus() != 0 || orgEntity.getLockStatus() != LockStatusEnum.NORMAL.getValue()) {
            throw new ActionException(ResultCode.AUTH_ACCESS_DENIED.getValue(), "当前数据不能被编辑");
        }
        SafeInterceptEntity entity = ConvertUtil.map(args, SafeInterceptEntity.class);
        // 更新数据
        boolean result = super.updateById(entity);
        if (!result) {
            throw new ActionException(ResultCode.DATABASE_UPDATE_ERROR);
        }
        // 保存明细
        saveDetails(entity.getInterceptId(), args);
    }

    /**
     * 保存凭证/预警拦截规则/预警拦截规对象
     *
     * @param interceptId 预警拦截id
     * @param args
     * @throws RuntimeException
     */
    private void saveDetails(String interceptId, SafeInterceptArgs args) throws RuntimeException {
        // 凭证信息添加
        List<SafeCredentialArgs> credentialList = args.getCredentialList();
        if (credentialList != null && credentialList.size() > 0) {
            credentialList.forEach(v -> {
                v.setCredentialId(null);
                v.setBusiId(interceptId);
            });
            credentialService.batchSave(credentialList);
        }
        // 保存预警拦截规则
        args.getInterceptRuleList().forEach(v -> {
            v.setInterceptId(interceptId);
        });
        interceptRuleService.batchSave(args.getInterceptRuleList());
        // 保存预警拦截规对象
        if (args.getInterceptTargetList() != null && args.getInterceptTargetList().size() > 0) {
            args.getInterceptTargetList().forEach(v -> {
                v.setInterceptId(interceptId);
            });
            interceptTargetService.batchSave(args.getInterceptTargetList());
        }
    }

    @Override
    public void submit(SafeInterceptApplyArgs args) throws RuntimeException {
        // 查询数据是否存在
        SafeInterceptEntity entity = this.getEntityById(args.getInterceptId());
        if (entity.getApproveStatus() != 0 || entity.getLockStatus() != LockStatusEnum.NORMAL.getValue()) {
            throw new ActionException(ResultCode.AUTH_ACCESS_DENIED.getValue(), "当前数据不能被提交");
        }
        entity.setApproveStatus(10);
        boolean result = super.updateById(entity);
        if (!result) {
            throw new ActionException(ResultCode.DATABASE_UPDATE_ERROR);
        }
        // 审批意见
        AddSafeApproveArgs safeApproveArgs = new AddSafeApproveArgs();
        safeApproveArgs.setBusinessId(args.getInterceptId());
        safeApproveArgs.setApproveType(entity.getInterceptType());
        safeApproveArgs.setHandlePersonId(args.getHandlePersonId());
        safeApproveArgs.setHandlePersonName(args.getHandlePersonName());
        safeApproveService.save(safeApproveArgs);
    }

    @Override
    public void changeInsert(SafeInterceptArgs args) throws RuntimeException {
        // 查询数据是否存在
        SafeInterceptEntity entity = this.getEntityById(args.getInterceptId());
        if (entity.getApproveStatus() != 20 || entity.getLockStatus() != LockStatusEnum.NORMAL.getValue()) {
            throw new ActionException(ResultCode.AUTH_ACCESS_DENIED.getValue(), "当前数据不能进行变更");
        }
        entity.setLockStatus(LockStatusEnum.LOGGING_OUT.getValue());
        boolean result = super.updateById(entity);
        if (!result) {
            throw new ActionException(ResultCode.DATABASE_UPDATE_ERROR);
        }
        // 保存预警拦截信息
        args.setInterceptCode(entity.getInterceptCode());
        this.save(args);
    }

    @Override
    public void deleteApply(SafeInterceptApplyArgs args) throws RuntimeException {
        // 查询数据是否存在
        SafeInterceptEntity entity = this.getEntityById(args.getInterceptId());
        if (entity.getApproveStatus() != 20 || entity.getLockStatus() != LockStatusEnum.NORMAL.getValue()) {
            throw new ActionException(ResultCode.AUTH_ACCESS_DENIED.getValue(), "当前数据不能被删除");
        }
        entity.setLockStatus(LockStatusEnum.CANCELLING.getValue());
        boolean result = super.updateById(entity);
        if (!result) {
            throw new ActionException(ResultCode.DATABASE_UPDATE_ERROR);
        }
        // 追加要件
        this.appendCredential(args);
        // 审批意见
        AddSafeApproveArgs safeApproveArgs = new AddSafeApproveArgs();
        safeApproveArgs.setBusinessId(args.getInterceptId());
        safeApproveArgs.setApproveType(3);
        safeApproveArgs.setHandlePersonId(args.getHandlePersonId());
        safeApproveArgs.setHandlePersonName(args.getHandlePersonName());
        safeApproveService.save(safeApproveArgs);
    }

    /**
     * 追加要件信息
     *
     * @param args 请求参数
     */
    private void appendCredential(SafeInterceptApplyArgs args) {
        if (args.getCredentialInfoList() != null && args.getCredentialInfoList().size() > 0) {
            List<SafeCredentialDto> credentialDtoList = credentialService.selectListByModel(args.getInterceptId());
            List<SafeCredentialArgs> credentialArgsList = new ArrayList<>();
            if (credentialDtoList != null && credentialDtoList.size() > 0) {
                credentialArgsList = ConvertUtil.listAtoListB(credentialDtoList, SafeCredentialArgs.class);
            } else {
                SafeCredentialArgs safeCredentialArgs = new SafeCredentialArgs();
                safeCredentialArgs.setBusiId(args.getInterceptId());
                safeCredentialArgs.setCredentialType("复印件");
                safeCredentialArgs.setCredentialName("凭证");
                safeCredentialArgs.setCredentialCount(1);
                safeCredentialArgs.setCredentialPage(1);
                safeCredentialArgs.setFileType(0);
                safeCredentialArgs.setSortId(0);
                safeCredentialArgs.setInterOperateType(1);
                safeCredentialArgs.setNetOperateType(1);
                credentialArgsList.add(safeCredentialArgs);
            }
            for (SafeCredentialArgs item : credentialArgsList) {
                if (item.getCredentialName().equals("凭证")) {
                    item.getCredentialInfoList().addAll(args.getCredentialInfoList());
                    break;
                }
            }
            credentialService.batchSave(credentialArgsList);
        }
    }

    @Override
    public void approveSubmit(SafeApproveArgs args) throws RuntimeException {
        // 查询数据是否存在
        SafeApproveDto approveDto = safeApproveService.getById(args.getApproveId());
        // 修改审批信息
        safeApproveService.approveSave(args);
        // 更新预警拦截信息
        SafeInterceptEntity interceptEntity = this.getEntityById(approveDto.getBusinessId());
        interceptEntity.setLockStatus(LockStatusEnum.NORMAL.getValue());
        if (approveDto.getApproveType() == 1 || approveDto.getApproveType() == 2) {
            interceptEntity.setApproveTime(new Date());
            interceptEntity.setApproveStatus(args.getHandleResult() == 1 ? 20 : 30);
            interceptEntity.setVersion(1);
            // 变更数据修改原始预警拦截信息
            if (approveDto.getApproveType() == 2) {
                QueryWrapper<SafeInterceptEntity> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(SafeInterceptEntity::getInterceptCode, interceptEntity.getInterceptCode())
                        .eq(SafeInterceptEntity::getApproveStatus, 20)
                        .eq(SafeInterceptEntity::getLockStatus, LockStatusEnum.LOGGING_OUT.getValue());
                SafeInterceptEntity orgEntity = mapper.selectOne(queryWrapper);
                if (orgEntity == null) {
                    throw new ActionException(ResultCode.VERIFICATION_FAILED.getValue(), "未查询到变更前的预警拦截信息");
                }
                orgEntity.setLockStatus(LockStatusEnum.NORMAL.getValue());
                if (args.getHandleResult() == 1) {
                    orgEntity.setApproveStatus(40);
                    orgEntity.setHistoryType(20);
                    interceptEntity.setVersion(orgEntity.getVersion() + 1);
                }
                super.updateById(orgEntity);
            }
        } else if (approveDto.getApproveType() == 3) {
            if (args.getHandleResult() == 1) {
                interceptEntity.setApproveStatus(40);
                interceptEntity.setHistoryType(30);
            }
        } else {
            throw new ActionException(ResultCode.AUTH_ACCESS_DENIED.getValue(), "审批类型有误");
        }
        super.updateById(interceptEntity);
    }

    @Override
    public IPage<SafeInterceptPageDto> page(SafeInterceptPageArgs args) throws RuntimeException {
        args.setOrgId(contextHolderUtils.getCurrentOrgId());
        args.setIdcardEncry(encryptor.encrypt(args.getKeyword()));
        return mapper.page(args.getQueryPage(), args);
    }

    @Override
    public SafeInterceptEntity getEntityById(String id) throws RuntimeException {
        SafeInterceptEntity entity = super.getById(id);
        if (entity == null) {
            throw new ActionException(ResultCode.DATABASE_NODATA);
        }
        return entity;
    }

    @Override
    public SafeInterceptDto getById(String id) throws RuntimeException {
        SafeInterceptEntity entity = super.getById(id);
        if (entity == null) {
            throw new ActionException(ResultCode.DATABASE_NODATA);
        }
        SafeInterceptDto interceptDto = ConvertUtil.map(entity, SafeInterceptDto.class);
        // 凭证信息
        interceptDto.setCredentialList(credentialService.selectListByModel(id));
        // 规则信息
        interceptDto.setInterceptRuleList(interceptRuleService.selectListByModel(id));
        // 对象信息
        interceptDto.setInterceptTargetList(interceptTargetService.selectListByModel(id));
        // 审批意见
        interceptDto.setApproveList(safeApproveService.selectByBusinessId(id));
        return interceptDto;
    }


    @Override
    public void deletedById(String interceptId) throws RuntimeException {
        // 查询数据是否存在
        SafeInterceptEntity interceptEntity = this.getEntityById(interceptId);
        if (interceptEntity.getApproveStatus() == 10 || interceptEntity.getApproveStatus() == 20) {
            throw new ActionException(ResultCode.AUTH_ACCESS_DENIED.getValue(), "当前数据不能被删除");
        }
        if (interceptEntity.getInterceptType() == 2 && interceptEntity.getApproveStatus() != 30) {
            QueryWrapper<SafeInterceptEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SafeInterceptEntity::getInterceptCode, interceptEntity.getInterceptCode())
                    .eq(SafeInterceptEntity::getApproveStatus, 20)
                    .eq(SafeInterceptEntity::getLockStatus, LockStatusEnum.LOGGING_OUT.getValue());
            SafeInterceptEntity orgEntity = mapper.selectOne(queryWrapper);
            if (orgEntity == null) {
                throw new ActionException(ResultCode.VERIFICATION_FAILED.getValue(), "未查询到变更前的预警拦截信息");
            }
            orgEntity.setLockStatus(LockStatusEnum.NORMAL.getValue());
            super.updateById(orgEntity);
        }
        this.removeById(interceptId);
    }
}